package com.code2roc.fastboot.framework.database;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.code2roc.fastboot.framework.model.BaseModel;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class BatchSQLUtil {

    public static BatchTableInfo getTableInsertInfo(BaseModel model) {
        BatchTableInfo insertInfo = new BatchTableInfo();
        String insertSQL = "";
        List<String> paramNameList = new ArrayList<>();
        List<BatchColumnInfo> paramValueList = new ArrayList<>();
        try {
            TableName tableNameAnno = model.getClass().getAnnotation(TableName.class);
            String tableName = tableNameAnno.value();
            for (Field field : model.getClass().getDeclaredFields()) {
                if (!Modifier.isStatic(field.getModifiers()) && (field.isAnnotationPresent(TableField.class) || field.isAnnotationPresent(TableId.class))) {
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(TableField.class)) {
                        TableField tableField = field.getAnnotation(TableField.class);
                        if (tableField.exist()) {
                            String name = tableField.value();
                            Object value = field.get(model);
                            paramNameList.add(name);
                            BatchColumnInfo columnInfo = new BatchColumnInfo();
                            columnInfo.setValue(value);
                            Class filedClass = field.getType();
                            if (filedClass == String.class) {
                                columnInfo.setSqlType(Types.VARCHAR);
                            } else if (filedClass == Integer.TYPE || filedClass == Integer.class) {
                                columnInfo.setSqlType(Types.INTEGER);
                            } else if (filedClass == Double.TYPE || filedClass == Double.class) {
                                columnInfo.setSqlType(Types.DOUBLE);
                            } else if (filedClass == Boolean.TYPE || filedClass == Boolean.class) {
                                columnInfo.setSqlType(Types.BOOLEAN);
                            } else if (filedClass == BigDecimal.class) {
                                columnInfo.setSqlType(Types.DECIMAL);
                            } else if (filedClass == Date.class) {
                                columnInfo.setSqlType(Types.DATE);
                            }
                            paramValueList.add(columnInfo);
                        }
                    }
                    if (field.isAnnotationPresent(TableId.class)) {
                        TableId tableId = field.getAnnotation(TableId.class);
                        String name = tableId.value();
                        Object value = field.get(model);
                        paramNameList.add(name);
                        BatchColumnInfo columnInfo = new BatchColumnInfo();
                        columnInfo.setValue(value);
                        Class filedClass = field.getType();
                        if (filedClass == String.class) {
                            columnInfo.setSqlType(Types.VARCHAR);
                        } else if (filedClass == Integer.TYPE || filedClass == Integer.class) {
                            columnInfo.setSqlType(Types.INTEGER);
                        } else if (filedClass == Double.TYPE || filedClass == Double.class) {
                            columnInfo.setSqlType(Types.DOUBLE);
                        } else if (filedClass == Boolean.TYPE || filedClass == Boolean.class) {
                            columnInfo.setSqlType(Types.BOOLEAN);
                        } else if (filedClass == BigDecimal.class) {
                            columnInfo.setSqlType(Types.DECIMAL);
                        } else if (filedClass == Date.class) {
                            columnInfo.setSqlType(Types.DATE);
                        }
                        paramValueList.add(columnInfo);
                    }
                }
            }
            insertSQL += "insert into " + tableName + " ( ";
            for (String name : paramNameList) {
                insertSQL += name + ",";
            }
            insertSQL = insertSQL.substring(0, insertSQL.length() - 1);
            insertSQL += " ) values ( ";
            for (String name : paramNameList) {
                insertSQL += "?,";
            }
            insertSQL = insertSQL.substring(0, insertSQL.length() - 1);
            insertSQL += " )";
        } catch (Exception e) {
            e.printStackTrace();
        }
        insertInfo.setSqlText(insertSQL);
        insertInfo.setParamList(paramValueList);
        return insertInfo;
    }

    public static BatchTableInfo getTableUpdateInfo(BaseModel model) {
        BatchTableInfo updateInfo = new BatchTableInfo();
        String updateSQL = "";
        List<String> paramNameList = new ArrayList<>();
        List<BatchColumnInfo> paramValueList = new ArrayList<>();
        List<String> ignoreUpdateFieldNameList = new ArrayList<>();
        ignoreUpdateFieldNameList.add("id");
        ignoreUpdateFieldNameList.add("row_id");
        ignoreUpdateFieldNameList.add("sort_num");
        ignoreUpdateFieldNameList.add("gmt_create");
        ignoreUpdateFieldNameList.add("gmt_modified");
        try {
            TableName tableNameAnno = model.getClass().getAnnotation(TableName.class);
            String keyName = "";
            String keyValue = "";
            String tableName = tableNameAnno.value();
            for (Field field : model.getClass().getDeclaredFields()) {
                if (!Modifier.isStatic(field.getModifiers()) && (field.isAnnotationPresent(TableField.class) || field.isAnnotationPresent(TableId.class))) {
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(TableField.class)) {
                        TableField tableField = field.getAnnotation(TableField.class);
                        if (tableField.exist()) {
                            String name = tableField.value();
                            if(!ignoreUpdateFieldNameList.contains(name.toLowerCase())){
                                Object value = field.get(model);
                                paramNameList.add(name);
                                BatchColumnInfo columnInfo = new BatchColumnInfo();
                                columnInfo.setValue(value);
                                Class filedClass = field.getType();
                                if (filedClass == String.class) {
                                    columnInfo.setSqlType(Types.VARCHAR);
                                } else if (filedClass == Integer.TYPE || filedClass == Integer.class) {
                                    columnInfo.setSqlType(Types.INTEGER);
                                } else if (filedClass == Double.TYPE || filedClass == Double.class) {
                                    columnInfo.setSqlType(Types.DOUBLE);
                                } else if (filedClass == Boolean.TYPE || filedClass == Boolean.class) {
                                    columnInfo.setSqlType(Types.BOOLEAN);
                                } else if (filedClass == BigDecimal.class) {
                                    columnInfo.setSqlType(Types.DECIMAL);
                                } else if (filedClass == Date.class) {
                                    columnInfo.setSqlType(Types.DATE);
                                }
                                paramValueList.add(columnInfo);
                            }
                        }
                    }
                    if (field.isAnnotationPresent(TableId.class)) {
                        TableId tableId = field.getAnnotation(TableId.class);
                        String name = tableId.value();
                        keyName = tableId.value();
                        Object value = field.get(model);
                        paramNameList.add(name);
                        BatchColumnInfo columnInfo = new BatchColumnInfo();
                        columnInfo.setValue(value);
                        updateInfo.setKeyValue(value);
                        Class filedClass = field.getType();
                        if (filedClass == String.class) {
                            columnInfo.setSqlType(Types.VARCHAR);
                        } else if (filedClass == Integer.TYPE || filedClass == Integer.class) {
                            columnInfo.setSqlType(Types.INTEGER);
                        } else if (filedClass == Double.TYPE || filedClass == Double.class) {
                            columnInfo.setSqlType(Types.DOUBLE);
                        } else if (filedClass == Boolean.TYPE || filedClass == Boolean.class) {
                            columnInfo.setSqlType(Types.BOOLEAN);
                        } else if (filedClass == BigDecimal.class) {
                            columnInfo.setSqlType(Types.DECIMAL);
                        } else if (filedClass == Date.class) {
                            columnInfo.setSqlType(Types.DATE);
                        }
                        paramValueList.add(columnInfo);
                    }
                }
            }
            updateSQL += "update  " + tableName + " set ";
            for (String name : paramNameList) {
                updateSQL += name + "=?,";
            }
            updateSQL = updateSQL.substring(0, updateSQL.length() - 1);
            updateSQL += " where " + keyName + "=?";
        } catch (Exception e) {
            e.printStackTrace();
        }
        updateInfo.setSqlText(updateSQL);
        updateInfo.setParamList(paramValueList);
        return updateInfo;
    }
}
